#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<termio.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

int cmdon_length = 7;
unsigned char cmdon[7] = { 0x40, 0x05, 0x01, 0x00, 0x2A, 0xFF, 0x01 };

int cmdoff_length = 7;
unsigned char cmdoff[7] = { 0x40, 0x05, 0x01, 0x00, 0x2A, 0xFF, 0x00 };
int fdUsbPort = -1; /* ttyUSB0 file descriptor */

static ssize_t writen(int fd, const void *vptr, size_t n) {
    /* Write "n" bytes to a descriptor. */
    size_t		nleft;
    ssize_t		nwritten;
    const char	*ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;		/* and call write() again */
            else
                return(-1);			/* error */
        }

        nleft -= nwritten;
        ptr   += nwritten;
    }
    return(n);
}

static void errno_exit(const char *s) {
    perror(s);
    exit(EXIT_FAILURE);
}

static int usbPortWrite(const unsigned char *cmd, int length) {
    unsigned char verify = 0;
    int i;
    if(fdUsbPort == -1)
        return -1;

    for(i = 0; i < length; i++) {
        writen(fdUsbPort, &cmd[i], sizeof(char));
        verify += cmd[i];
    }
    writen(fdUsbPort, &verify, sizeof(char));
    tcflush(fdUsbPort, TCOFLUSH);
    return 0;
}

int usbPort_init(void) {
    int ret;
    if(fdUsbPort != -1)
        return 0;

    fdUsbPort = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
    if(fdUsbPort == -1)
        errno_exit("failed to open tty\n");

    tcflush(fdUsbPort, TCIOFLUSH);
    struct termios portAttr;
    tcgetattr(fdUsbPort, &portAttr);
    cfsetispeed(&portAttr,B19200);
    cfsetospeed(&portAttr,B19200);
    ret = tcsetattr(fdUsbPort, TCSANOW, &portAttr);
    if(ret < 0)
        errno_exit("tcsetattr() failed to set the attr");
    return 0;

}

int usbPort_allon(void) {
    return usbPortWrite(cmdon, cmdon_length);
}

int usbPort_alloff(void) {
    return usbPortWrite(cmdoff, cmdoff_length);
}

void usbPort_exit(void) {
    if(fdUsbPort != -1)
        close(fdUsbPort);
}

int main(int argc, char **argv) {
    usbPort_init();
    int i;
    for(i = 0; i < 1; i++) {
        usbPort_allon();
        usleep(1000);
        usbPort_alloff();
        usleep(1000);
    }
    usbPort_allon();
    usleep(1000);
    usbPort_exit();
    return 0;
}
